#!/usr/bin/env python

import socket, thread, threading, select, time, sys, random, wx, numpy,re

###################################################
# Definition de la classe demineur
###################################################


joueurs=[]
pourcents=[]
Games=[]
TAILLE_BLOC=4000

verrouC=threading.Lock()

# Variables graphiques
Centrage={10:210,15:150,25:0}
TAILLE_CASE=25
TAILLE_MENU=30

###################################################
# Definition de la classe demineur
###################################################

class pyDemin:
    def __init__(self,nbMine,w,h):
        self.nbmine=nbMine
        self.w=w
        self.h=h
        self.debut=time.time()
        self.fin=self.debut
        self.state="Running"

        self.grilleM=[0]*(self.w*self.h-self.nbmine)
        for i in range(nbMine):
            self.grilleM.append("X")
        random.shuffle(self.grilleM)
        self.grilleM=numpy.reshape(self.grilleM,(self.w,self.h))
        for i in range(self.w):
            for j in range(self.h):
                self.grilleM[i][j]=self.count_mine(self.grilleM,[i,j])
        self.grilleD=numpy.ones((self.w,self.h))

    def __init__(self):
        self.nbmine=0
        self.w=0
        self.h=0
        self.debut=time.time()
        self.fin=self.debut
        self.state="Waiting"
        self.grilleM=[]
        self.grilleD=[]

    def Reset(self):
        NG=[0]*(self.w*self.h-self.nbmine)
        for i in range(self.nbmine):
            NG.append("X")
        random.shuffle(NG)
        self.grilleM=numpy.reshape(NG,(self.w,self.h))
        self.grilleD=numpy.ones((self.w,self.h))
        for i in range(self.w):
            for j in range(self.h):
                self.grilleM[i][j]=self.count_mine(self.grilleM,[i,j])
        self.debut=time.time()
        self.fin=self.debut
        self.state="Running"
        
    def Reset1(self,grille):
        self.grilleM=grille
        self.grilleD=numpy.ones((self.w,self.h))
        for i in range(self.w):
            for j in range(self.h):
                self.grilleM[i][j]=self.count_mine(self.grilleM,[i,j])
        self.debut=time.time()
        self.fin=self.debut
        self.state="Running"        

    def count_mine(self,tab,indice):
        if(tab[indice[0]][indice[1]]=="X"):
            return "X"
        else:
            count=0
            indx=0
            indy=0
            for i in range(-1,2,1):
                for j in range(-1,2,1):
                    indx=indice[0]+i
                    indy=indice[1]+j
                    if(indx>=0 and indx <self.w  and indy>=0 and indy < self.h):
                        if(tab[indx][indy]=="X" and ((i==0 and j==0)==False)):
                            count+=1
            return count

    def __repr__(self):
        print "Jeu decouvert :\n"
        print self.grilleM
        print "\nGrille de jeu :\n"
        print self.grilleD
        print self.w,self.h,self.nbmine
        return ""

    def Decouvre(self,indice):
        if self.grilleD[indice[0]][indice[1]] != 2:
            self.grilleD[indice[0]][indice[1]]=0
            return self.grilleM[indice[0]][indice[1]]

    def Renvoire(self,indice):
        list=[]
        count=0
        indx=0
        indy=0
        for i in range(-1,2,1):
            for j in range(-1,2,1):
                indx=indice[0]+i
                indy=indice[1]+j
                if(indx>=0 and indx <self.w  and indy>=0 and indy < self.h):
                    count=self.count_mine(self.grilleM,[indx,indy])
                    if(count>=0):
                        if((i==0 and j==0)==False):
                            list.append([indx,indy])
        return list

    def Decouvrement(self,indice):
        if self.grilleD[indice[0]][indice[1]] == 1:
            if self.Decouvre(indice)=="0":
                list=self.Renvoire(indice)
                for x in list:
                    self.Decouvrement(x)
            else:
                self.Decouvre(indice)
        if self.grilleM[indice[0]][indice[1]] == "X":
            print "Perdu !"
        return

    def Flaf(self,indice):
        self.grilleD[indice[0]][indice[1]]=2

    def UnFlaf(self,indice):
        self.grilleD[indice[0]][indice[1]]=1



###################################################
# Definition de la classe Board
###################################################


class BoardWindow(wx.Panel):
	def __init__(self, parent, ID, name, mode,creator):
		wx.Panel.__init__(self,parent,ID)
		self.SetSize(parent.GetClientSize())
		self.Bind(wx.EVT_PAINT,self.OnPaint)
                self.creator=creator
                self.pseudo=name
                self.mode=mode
                self.Demineur=pyDemin()
                self.nbPlayers=2
                self.gameName="Game"
                self.level=1
                self.Choice=""
                self.init_buffer()

	def OnPaint(self,evt):
		dc = wx.BufferedPaintDC(self,self.buffer)
                #self.init_buffer()

	def init_buffer(self):
		w,h = self.GetClientSize()
		self.buffer = wx.EmptyBitmap(w,h)
		dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
		self.draw(dc)


	def draw(self,dc):
		dc.Clear()
		dc.SetBrush(wx.Brush("grey"))
		dc.SetPen(wx.Pen("black",3))

		# Definition des boutons
		dc.DrawLine(0,60,250,60)

		if(self.pseudo == ""):
			print "C> Reception du nom du Joueur \n"
			verrouC.acquire()
			self.pseudo=s.recv(255)
			verrouC.release()
			print "C> %s connecte \n"%self.pseudo

		Name = wx.Button(self, -1, "Enter Your Name", (50,70),(150,25))
		self.Bind(wx.EVT_BUTTON, self.ChangeName,Name)
		dc.DrawText("Current name : %s"%self.pseudo,45,100)

		Solo=wx.Button(self,-1,"Solo",(40,140),(60,25))
		self.Bind(wx.EVT_BUTTON,self.SetSolo,Solo)

		Reseau=wx.Button(self,-1,"Online",(150,140),(60,25))
		self.Bind(wx.EVT_BUTTON,self.SetReseau,Reseau)

		if self.mode == "Solo":
			Reseau.Enable()
			Solo.Disable()
		
			rb1=wx.RadioButton(self, -1, 'Rookie', (100,200),style=wx.RB_GROUP)
			self.Bind(wx.EVT_RADIOBUTTON,self.SetRookie,rb1)

			rb2=wx.RadioButton(self,-1,"Pro",(100,230))
			self.Bind(wx.EVT_RADIOBUTTON,self.SetPro,rb2)

			rb3=wx.RadioButton(self,-1,"Star",(100,260))
			self.Bind(wx.EVT_RADIOBUTTON,self.SetStar,rb3)

			New=wx.Button(self,-1,"New",(40,330),(60,25))
			self.Bind(wx.EVT_BUTTON,self.newgame,New)

			Score=wx.Button(self,-1,"Score",(150,330),(60,25))
			self.Bind(wx.EVT_BUTTON,self.score,Score)

		if self.mode == "Online":
			Reseau.Disable()
			Solo.Enable()
		
			Create=wx.Button(self,-1,"Create",(40,180),(60,25))
			self.Bind(wx.EVT_BUTTON,self.Create,Create)

			Join=wx.Button(self,-1,"Join",(150,180),(60,25))
			self.Bind(wx.EVT_BUTTON,self.Join,Join)

			if self.creator=="Create":
				Create.Disable()
				Join.Enable()
				
				dc.DrawText("Number of Players : ",30,225)
				t1 = wx.TextCtrl(self, -1, "", size=(25,25),pos=(170,220))
				self.Bind(wx.EVT_TEXT, self.EvtTextNbPlayers, t1)
	      
				rb1=wx.RadioButton(self, -1, 'Rookie', (100,260),style=wx.RB_GROUP)
				self.Bind(wx.EVT_RADIOBUTTON,self.SetRookie,rb1)

				rb2=wx.RadioButton(self,-1,"Pro",(100,290))
				self.Bind(wx.EVT_RADIOBUTTON,self.SetPro,rb2)

				rb3=wx.RadioButton(self,-1,"Star",(100,320))
				self.Bind(wx.EVT_RADIOBUTTON,self.SetStar,rb3)

				dc.DrawText("Description : ",30,350)
				t1 = wx.TextCtrl(self, -1, "", size=(100,25),pos=(110,350))
				self.Bind(wx.EVT_TEXT, self.EvtTextGameName, t1)
				
				Launch=wx.Button(self,-1,"Launch",size=(190,40),pos=(30,400))
				self.Bind(wx.EVT_BUTTON,self.Launch,Launch)

			elif  self.creator == "Join":
				Join.Disable()
				Create.Enable()
			
				print "Mode Join Active : %d Parties Dispo\n"%(len(Games))
				if len(Games)!=0:
					dc.DrawText("List of Available Games",50,220)
					for i in range(len(Games)):
						tmp=Games[i].split(" ")
						txt="%s, %s Players, %s"%(tmp[0],tmp[1],numberToLevel(int(tmp[2])))
						cb=wx.CheckBox(self, -1, txt, (40,250+20*i))
						self.Bind(wx.EVT_CHECKBOX,self.SetJoin,cb)
					Rejoin=wx.Button(self,-1,"Rejoin",size=(190,40),pos=(30,400))
					self.Bind(wx.EVT_BUTTON,self.Rejoin,Rejoin)		
				else:
					dc.DrawText("No Game Available",65,300)
									
			
			elif self.creator == "Online":
				if len(Games)!=0:
					dc.DrawText("List of Available Games",50,220)
					for i in range(len(Games)):
						tmp=Games[i].split(" ")
						txt="%s, %s Players, %s"%(tmp[0],tmp[1],numberToLevel(int(tmp[2])))
						dc.DrawText(txt,50,250+20*i)
				else:
					dc.DrawText("No Game Available",65,300)
				

		Quit=wx.Button(self,1,"Quit",(95,470),(60,25))
		self.Bind(wx.EVT_BUTTON,self.sortie,Quit)

		self.SetAutoLayout(True)


	def sortie(self,event):
		self.GetParent().Destroy()
		self.Destroy()
		data="quit"
		verrouC.acquire()
		s.send(data)
		verrouC.release()
		print("C> Envoi (sortie) de : %s\n"%data)    
		s.close

	def score(self,event):
            win = ScoreFrame(self, -1,"High Score", size=(600, 300),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)

	def newgame(self,event):
            if self.Demineur.w == 0:
               #print "Choisir un niveau de jeu"
               self.init_buffer()
               winE = ErrorFrame(None, -1, "Error", size=(200,100),style = wx.DEFAULT_FRAME_STYLE)
               winE.Show(True)
            else:
                self.Demineur.Reset()
                self.init_buffer()
                winJ = GameFrame(None, -1, "Mine Sweeper %s"%self.pseudo, self.Demineur,self.pseudo, size=(self.Demineur.w*TAILLE_CASE,self.Demineur.w*TAILLE_CASE+60),style = wx.DEFAULT_FRAME_STYLE)
                winJ.Show(True)
                #self.GetParent().Destroy()

	def ChangeName(self, event):
            dlg = wx.TextEntryDialog(self, 'Enter your name','', '')
            if dlg.ShowModal() == wx.ID_OK:
                self.pseudo=dlg.GetValue()
            dlg.Destroy()
            self.init_buffer()
	    if self.pseudo[:5] != "Joueur":
	      data="name %s"%self.pseudo
	      verrouC.acquire()
	      s.send(data)
	      verrouC.release()
	      print("C> Envoi (changename) de : %s\n"%data)                	      

        def EvtTextNbPlayers(self, event):
            print 'Joueurs : %s\n' % event.GetString()
            self.nbPlayers=int(event.GetString())
        
        def EvtTextGameName(self, event):
           	print 'Nom Partie: %s\n' % event.GetString()
           	self.gameName=event.GetString()

        def SetSolo(self,event):
            win = BoardFrame(None, -1, "Mine Sweeper", self.pseudo,"Solo","",pos=self.GetParent().GetPosition(),size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)
            self.GetParent().Destroy()

        def SetReseau(self,event):
            data="online"
            verrouC.acquire()
            s.send(data)
            verrouC.release()
            print("C> Envoi (SetReseau) de : %s\n"%data)
            verrouC.acquire()
            data=s.recv(TAILLE_BLOC)
            verrouC.release()
            print("C> recu (online) : %s \n"%data)
            if data!= "Aucune partie disponible":
            	tab=eval(data)
            	for i in range(len(tab)):
            		if Games.count(tab[i])==0:
            		   	Games.append(tab[i])
             			print "C> ajout de %s \n"%(tab[i])
            win = BoardFrame(None, -1, "Mine Sweeper", self.pseudo,"Online","Online", pos=self.GetParent().GetPosition(),size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)
            self.GetParent().Destroy()
            
        def SetJoin(self,event):
        	self.Choice=(event.GetEventObject().GetLabel().split(","))[0]
        	print "Choix : %s\n"%self.Choice
        	self.level=levelToNumber(((event.GetEventObject().GetLabel().split(","))[2])[1:])
        	print self.level
        	if self.level==1:
        		self.Demineur.w=10
        		self.Demineur.h=10
        		self.Demineur.nbmine=15        		
        	elif self.level==2:
        		self.Demineur.w=15
        		self.Demineur.h=15
        		self.Demineur.nbmine=40
        	elif self.level==3:
        		self.Demineur.w=25
        		self.Demineur.h=25
        		self.Demineur.nbmine=100     
        	print self.Demineur.w   	

        def Rejoin(self,event):
        	event.GetEventObject().Disable()
        	print "C> Rejoint la partie %s\n"%self.Choice
        	verrouC.acquire()
        	s.send(self.Choice)
        	verrouC.release()
        	data = '#'
        	while data:
                    verrouC.acquire()
                    data = s.recv(TAILLE_BLOC)
                    verrouC.release()
                    print "C> Recoit %s \n"%data
                    if data=="Ready": 
			data=False
        	verrouC.acquire()		
        	data=s.recv(TAILLE_BLOC)
        	verrouC.release()
        	print "recoit %s \n"%data
        	data=eval(data)	
        	tabPlayers=data[0]
        	grid=numpy.array(data[1])
        	self.Demineur.Reset1(grid)
        	self.init_buffer()
        	winJ = GameFrameRes(self, -1, "Mine Sweeper %s"%self.pseudo, self.Demineur,self.pseudo,tabPlayers,size=(self.Demineur.w*TAILLE_CASE+10*TAILLE_CASE,self.Demineur.w*TAILLE_CASE),style = wx.DEFAULT_FRAME_STYLE)
        	winJ.Show(True)
        	print "Debut de la partie \n"
        	         	       			              	

        def Create(self,event):
            win = BoardFrame(None, -1, "Mine Sweeper", self.pseudo,"Online","Create", pos=self.GetParent().GetPosition(),size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)
            self.GetParent().Destroy()
            data="create"
            s.send(data)
            print("C> Envoi (create) de : %s\n"%data)                


        def Launch(self,event):
            event.GetEventObject().Disable()
            data=[]        
            if self.Demineur.w == 0:
                self.SetRookie(0)
            data.append(self.gameName)
            data.append(self.nbPlayers)
            data.append(self.level)
            Games.append("%s 1/%d %d"%(self.gameName,self.nbPlayers,self.level)) 
            print "Ajout de la partie\n"
            print("C> Lancement de la partie %s , 1/%d, %d \n"%(self.gameName,self.nbPlayers,self.level))			
            data=str(data)
            verrouC.acquire()
            s.send(data)
            verrouC.release()
            print("C> Envoi (launch) de : %s\n"%data)
            dlg = wx.MessageDialog(self, 'Please Wait For Additional Players','The Game Will Begin Soon',wx.OK)
            #dlg=WaitFrame(None,-1,"Wait",size=(250,100),style=wx.DEFAULT_FRAME_STYLE)
            #dlg.Show(True)
            dlg.ShowModal()
            dlg.Destroy()
            #print "#"
            data = '#'
            print "plop1"
            while data:
		print "plop2"
		verrouC.acquire()
		data = s.recv(10)
		verrouC.release()
		print "C> Recoit %s \n"%data
		if data=="Ready":
		    #print "envoi de ok"
                    #s.send("%s ok"%self.pseudo)
                    print "plop3" 
                    data=False
            #dlg.Destroy()
            print "plop4"
            verrouC.acquire()		
            data=s.recv(TAILLE_BLOC)
            verrouC.release()
            print "recoit %s \n"%data
            data=eval(data)	
            tabPlayers=data[0]
            grid=numpy.array(data[1])
            self.Demineur.Reset1(grid)
            self.init_buffer()
            #s.send("ok")
            winJ = GameFrameRes(self, -1, "Mine Sweeper %s"%self.pseudo, self.Demineur,self.pseudo,tabPlayers, size=(self.Demineur.w*TAILLE_CASE+10*TAILLE_CASE,self.Demineur.w*TAILLE_CASE),style = wx.DEFAULT_FRAME_STYLE)
            winJ.Show(True)
            print "Debut de la partie \n"
    
	def Join(self,event):
            data="join"
            verrouC.acquire()
            s.send(data)
            verrouC.release()
            print("C> Envoi (join) de : %s\n"%data)     
            win = BoardFrame(None, -1, "Mine Sweeper", self.pseudo,"Online","Join", pos=self.GetParent().GetPosition(),size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)
            self.GetParent().Destroy()

	def SetRookie(self,event):
            self.Demineur.w=10
            self.Demineur.h=10
            self.Demineur.nbmine=15
            self.Demineur.Reset()
            self.level=1
     

   	def SetPro(self,event):
            self.Demineur.w=15
            self.Demineur.h=15
            self.Demineur.nbmine=40
            self.Demineur.Reset()
            self.level=2

	def SetStar(self,event):
            self.Demineur.w=25
            self.Demineur.h=25
            self.Demineur.nbmine=100
            self.Demineur.Reset()
            self.level=3

def numberToLevel(level):
	if level==1:
            return "Rookie"
	elif level==2:
            return "Pro"
	else:
            return "Star"
		
def levelToNumber(level):
	if level=="Rookie":
            return 1
	elif level=="Pro":
            return 2
	else:
            return 3

class BoardFrame(wx.Frame):
	def __init__( self, parent, ID, title,name,mode, creator,pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
            wx.Frame.__init__(self, parent, ID, title, pos, size, style)
            self.SetAutoLayout(True)
            self.BoardWindow = BoardWindow(self,-1,name,mode,creator)
            self.BoardWindow.init_buffer()

class Partie:

    def __init__(self, name, level,tabPlayers, grid):
        self.name=name
        self.nbPlayers=len(tabPlayers)
        self.level=level
	self.grid=grid
        self.tabPlayers=tabPlayers
        print "C> Partie cree : %s %d %d \n"%(name,nbPlayers,level)



###################################################
# Definition de la classe Wait Frame
###################################################

class WaitWindow(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self, parent, -1)
        self.SetSize(parent.GetClientSize())
        self.init_buffer()
        self.Bind(wx.EVT_PAINT,self.OnPaint)

    def OnPaint(self,evt):
        dc = wx.BufferedPaintDC(self,self.buffer)

    def init_buffer(self):
        w,h = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(w,h)
        dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
        self.draw(dc)
        
    def draw(self,dc):
        dc.Clear()
        dc.SetBrush(wx.Brush("grey"))
        dc.SetPen(wx.Pen("black",3))
        self.SetAutoLayout(True)
        
        wx.StaticText(self, -1, "Waiting For Additional Players", (30, 15))
        #G = wx.Gauge(self, -1,50, (25, 50), (150, 25))
        #G.Pulse()

        Ok=wx.Button(self,-1,"Wait",(200,50),(50,25))
        self.Bind(wx.EVT_BUTTON,self.sortie,Ok)


        #G = wx.Gauge(self, -1,nombre total de joueur, (110, 95), (250, 25))
        #G.SetValue(nombre de joueur present)



    def sortie(self,event):
        self.GetParent().Destroy()



class WaitFrame(wx.Frame):
	def __init__( self, parent, ID, title, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
		wx.Frame.__init__(self, parent, ID, title, pos, size, style)

		self.SetAutoLayout(True)
		self.WaitWindow = WaitWindow(self)
		self.WaitWindow.init_buffer()

###################################################
# Definition de la classe Score Frame
###################################################

class ScoreWindow(wx.Panel):
	def __init__(self, parent, ID):
		wx.Panel.__init__(self,parent,ID)
		self.SetSize(parent.GetClientSize())
		self.init_buffer()
		self.Bind(wx.EVT_PAINT,self.OnPaint)

	def OnPaint(self,evt):
		dc = wx.BufferedPaintDC(self,self.buffer)

	def init_buffer(self):
		w,h = self.GetClientSize()
		self.buffer = wx.EmptyBitmap(w,h)
		dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
		self.draw(dc)

	def draw(self,dc):
		dc.Clear()
		dc.SetBrush(wx.Brush("grey"))
		dc.SetPen(wx.Pen("black",3))
		self.SetAutoLayout(True)

		Quit=wx.Button(self,2,"Close",(15,265),(60,25))
		self.Bind(wx.EVT_BUTTON,self.Quit,Quit)

		dc.DrawText("Rookie",30,15)
		dc.DrawText("Pro", 230,15)
		dc.DrawText("Star",430,15)

		f=open("HighScoreRookie.txt","r")
		list=f.readlines()
		for i in range(10):
			dc.DrawText(list[2*i],15,50+10*2*i)
			dc.DrawText(list[2*i+1],100,50+10*2*i)
		f.close()

		f=open("HighScorePro.txt","r")
		list=f.readlines()
		for i in range(10):
			dc.DrawText(list[2*i],215,50+10*2*i)
			dc.DrawText(list[2*i+1],300,50+10*2*i)
		f.close()

		f=open("HighScoreStar.txt","r")
		list=f.readlines()
		for i in range(10):
			dc.DrawText(list[2*i],415,50+10*2*i)
			dc.DrawText(list[2*i+1],500,50+10*2*i)
		f.close()

	def Quit(self,vevent):
		self.GetParent().Destroy()


class ScoreFrame(wx.Frame):
	def __init__( self, parent, ID, title, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
		wx.Frame.__init__(self, parent, ID, title, pos, size, style)

		self.SetAutoLayout(True)
		self.ScoreWindow = ScoreWindow(self,-1)
		self.ScoreWindow.init_buffer()


###################################################
# Definition de la classe Error Frame
###################################################

class ErrorWindow(wx.Panel):
	def __init__(self, parent, ID):
		wx.Panel.__init__(self,parent,ID)
		self.SetSize(parent.GetClientSize())
		self.init_buffer()
		self.Bind(wx.EVT_PAINT,self.OnPaint)

	def OnPaint(self,evt):
		dc = wx.BufferedPaintDC(self,self.buffer)

	def init_buffer(self):
		w,h = self.GetClientSize()
		self.buffer = wx.EmptyBitmap(w,h)
		dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
		self.draw(dc)

	def draw(self,dc):
		dc.Clear()
		dc.SetBrush(wx.Brush("grey"))
		dc.SetPen(wx.Pen("black",3))
		self.SetAutoLayout(True)

		Quit=wx.Button(self,2,"Ok",(70,60),(60,25))
		self.Bind(wx.EVT_BUTTON,self.Quit,Quit)

		dc.DrawText("Please select a level.",35,30)

	def Quit(self,vevent):
		self.GetParent().Destroy()


class ErrorFrame(wx.Frame):
	def __init__( self, parent, ID, title, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
		wx.Frame.__init__(self, parent, ID, title, pos, size, style)

		self.SetAutoLayout(True)
		self.ErrorWindow = ErrorWindow(self,-1)
		self.ErrorWindow.init_buffer()



###################################################
# Definition de la classe DeminWindow
###################################################

class DeminWindow(wx.Panel):
	def __init__(self, parent, ID,demineur,name):
		wx.Panel.__init__(self,parent,ID)
		self.SetSize(parent.GetClientSize())
		self.Bind(wx.EVT_PAINT,self.OnPaint)
		self.Bind(wx.EVT_LEFT_DOWN,self.OnLeft)
		self.Bind(wx.EVT_RIGHT_DOWN,self.OnRight)
                self.Dem=demineur
                self.name=name
                self.init_buffer()

	def OnLeft(self,evt):
		x,y = evt.GetPosition()
		x,y = self.Discretisation(x,y)
		if x >= 0 and y >= 0 and y < self.Dem.h and x < self.Dem.w:
			self.Dem.Decouvrement([x,y])
			self.init_buffer()

	def OnRight(self,evt):
		x,y = evt.GetPosition()
		x,y = self.Discretisation(x,y)
		if x >= 0 and y >= 0 and y < self.Dem.h and x < self.Dem.w:
			if(self.Dem.grilleD[x,y]==1):
				self.Dem.Flaf([x,y])
			elif self.Dem.grilleD[x,y]==2:
				self.Dem.UnFlaf([x,y])
			self.init_buffer()

	def OnPaint(self,evt):
		dc = wx.BufferedPaintDC(self,self.buffer)

	def init_buffer(self):
		w,h = self.GetClientSize()
		self.buffer = wx.EmptyBitmap(w,h)
		dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
		self.draw(dc)

	def draw(self,dc):
		dc.Clear()
		dc.SetBrush(wx.Brush("grey"))
		dc.SetPen(wx.Pen("black",1))
		count=self.Dem.nbmine
		flafmine=0

                x=(self.Dem.w*TAILLE_CASE-150)/4.0

                New=wx.Button(self,2,"New",(x,self.Dem.w*TAILLE_CASE+20),(50,25))
                self.Bind(wx.EVT_BUTTON,self.newgame,New)

                Back=wx.Button(self,4,"Back",(2*x+50,self.Dem.w*TAILLE_CASE+20),(50,25))
        	self.Bind(wx.EVT_BUTTON,self.sortie,Back)

                Score=wx.Button(self,3,"Score",(3*x+100,self.Dem.w*TAILLE_CASE+20),(50,25))
                self.Bind(wx.EVT_BUTTON,self.score,Score)

                self.SetAutoLayout(True)

		# Debut de la representation de la grille de jeu
                if self.Dem.state == "Running":
                    for i in range(self.Dem.w):
                        for j in range(self.Dem.h):
                            if(self.Dem.grilleD[i,j]==1):
                                dc.SetBrush(wx.Brush("grey"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                            elif self.Dem.grilleD[i,j]==0 and self.Dem.grilleM[i,j]!="X":
                                dc.SetBrush(wx.Brush("white"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                            elif self.Dem.grilleD[i,j] == 2:
                                dc.SetBrush(wx.Brush("blue"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                count-=1
                                if self.Dem.grilleM[i][j]=="X":
                                    flafmine+=1
                            elif self.Dem.grilleM[i,j]=="X":
                                dc.SetBrush(wx.Brush("red"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                dc.DrawText("X",i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                                if self.Dem.state == "Running":
                                    self.Dem.fin=time.time()
                                    self.Dem.state="Lost"

                if (flafmine == self.Dem.nbmine and count==0):
                    if self.Dem.state == "Running":
                        self.Dem.fin=time.time()
                        self.UpdateScore(self.Score(self.Dem),self.name)
                        self.Dem.state="Win"

                if self.Dem.state == "Lost":
                    for i in range(self.Dem.w):
                        for j in range(self.Dem.h):
                            if self.Dem.grilleM[i][j]=="X":
                                dc.SetBrush(wx.Brush("red"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                dc.DrawText("X",i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                            else :
                                dc.SetBrush(wx.Brush("white"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)

                elif self.Dem.state == "Win":
                    for i in range(self.Dem.w):
                        for j in range(self.Dem.h):
                            if self.Dem.grilleM[i][j]=="X":
                                dc.SetBrush(wx.Brush("blue"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                            else :
                                dc.SetBrush(wx.Brush("white"))
                                dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                                dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)


                x=(self.Dem.w-9)*TAILLE_CASE/3.0
                dc.DrawText("Nb mines left : %d"%count,2*x+4*TAILLE_CASE,self.Dem.h*TAILLE_CASE+3)
                dc.DrawText("Time : %.3f"%(self.Dem.fin-self.Dem.debut),x,self.Dem.h*TAILLE_CASE+3)


	def sortie(self,event):
            self.GetParent().Destroy()

	def newgame(self,event):
            self.Dem.Reset()
            self.init_buffer()

	def back(self,event):
            win = BoardFrame(None, -1, "Demineur",self.name, size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)
            self.GetParent().Destroy()

	def score(self,event):
            win = ScoreFrame(self, -1,"High Score", size=(600, 300),style = wx.DEFAULT_FRAME_STYLE)
            win.Show(True)

	def Discretisation(self,x,y):
		return x/TAILLE_CASE,y/TAILLE_CASE

	def Score(self,dem):
		return int(100000/(1+self.Dem.fin-self.Dem.debut))

	def UpdateScore(self,score,name):
		if self.Dem.w == 10:
			f=open("HighScoreRookie.txt","r")
		elif self.Dem.w == 15:
			f=open("HighScorePro.txt","r")
		else:
			f=open("HighScoreStar.txt","r")

		l=f.readlines()
		f.close()
		new=[]
		bool=True
		for i in range(10):
			if score >= float(l[2*i+1]) and bool:
				new.append(name+"\n")
				new.append("%.0f\n"%score)
				bool=False
			new.append(l[2*i])
			new.append(l[2*i+1])

		if self.Dem.w == 10:
			g=open("HighScoreRookie.txt","w")
		elif self.Dem.w == 15:
			g=open("HighScorePro.txt","w")
		else:
			g=open("HighScoreStar.txt","w")

		g.writelines(new)
		g.close()


class GameFrame(wx.Frame):
	def __init__( self, parent, ID, title, demineur, name,pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
		wx.Frame.__init__(self, parent, ID, title, pos, size, style)

		self.SetAutoLayout(True)
		self.GameWindow = DeminWindow(self,-1,demineur,name)
		self.GameWindow.init_buffer()

###################################################
# Definition de la classe DeminWindowRes
###################################################

class DeminWindowRes(wx.Panel):
       def __init__(self, parent, ID,demineur,name,tabPlayers):
               wx.Panel.__init__(self,parent,ID)
               self.SetSize(parent.GetClientSize())
               self.Bind(wx.EVT_PAINT,self.OnPaint)
               self.Bind(wx.EVT_LEFT_DOWN,self.OnLeft)
               self.Bind(wx.EVT_RIGHT_DOWN,self.OnRight)
               self.Dem=demineur
               self.name=name
	       self.tabPlayers=tabPlayers
	       self.nbPlayers=len(tabPlayers)
               self.init_buffer()

       def OnLeft(self,evt):
               x,y = evt.GetPosition()
               x,y = self.Discretisation(x,y)
               if x >= 0 and y >= 0 and y < self.Dem.h and x < self.Dem.w:
                       self.Dem.Decouvrement([x,y])
                       self.init_buffer()

       def OnRight(self,evt):
               x,y = evt.GetPosition()
               x,y = self.Discretisation(x,y)
               if x >= 0 and y >= 0 and y < self.Dem.h and x < self.Dem.w:
                       if(self.Dem.grilleD[x,y]==1):
                               self.Dem.Flaf([x,y])
                       elif self.Dem.grilleD[x,y]==2:
                               self.Dem.UnFlaf([x,y])
                       self.init_buffer()

       def OnPaint(self,evt):
               dc = wx.BufferedPaintDC(self,self.buffer)

       def init_buffer(self):
               w,h = self.GetClientSize()
               self.buffer = wx.EmptyBitmap(w,h)
               dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
               self.draw(dc)

       def draw(self,dc):
               dc.Clear()
               dc.SetBrush(wx.Brush("grey"))
               dc.SetPen(wx.Pen("black",1))
               count=self.Dem.nbmine
               flafmine=0
               Avancement=0 # Le score lors d'un jeu en reseau se resume au taux de visibilite de la grille

               New=wx.Button(self,2,"New",(self.Dem.w*TAILLE_CASE+50,self.Dem.w*TAILLE_CASE-30),(50,25))
               self.Bind(wx.EVT_BUTTON,self.newgame,New)

               Back=wx.Button(self,4,"Back",(self.Dem.w*TAILLE_CASE+150,self.Dem.w*TAILLE_CASE-30),(50,25))
               self.Bind(wx.EVT_BUTTON,self.sortie,Back)

               self.SetAutoLayout(True)

               # Debut de la representation de la grille de jeu
               if self.Dem.state == "Running":
                   for i in range(self.Dem.w):
                       for j in range(self.Dem.h):
                           if(self.Dem.grilleD[i,j]==1):
                               dc.SetBrush(wx.Brush("grey"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                           elif self.Dem.grilleD[i,j]==0 and self.Dem.grilleM[i,j]!="X":
                               dc.SetBrush(wx.Brush("white"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                               Avancement+=1
                           elif self.Dem.grilleD[i,j] == 2:
                               dc.SetBrush(wx.Brush("blue"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               count-=1
                               Avancement+=1
                               if self.Dem.grilleM[i][j]=="X":
                                   flafmine+=1
                           elif self.Dem.grilleM[i,j]=="X":
                               dc.SetBrush(wx.Brush("red"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               dc.DrawText("X",i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                               if self.Dem.state == "Running":
                                   self.Dem.fin=time.time()
                                   self.Dem.state="Lost"

               if (flafmine == self.Dem.nbmine and count==0):
                   if self.Dem.state == "Running":
                       self.Dem.fin=time.time()
                       self.Dem.state="Win"

               if self.Dem.state == "Lost":
		   Avancement=self.Dem.w*self.Dem.h
                   for i in range(self.Dem.w):
                       for j in range(self.Dem.h):
                           if self.Dem.grilleM[i][j]=="X":
                               dc.SetBrush(wx.Brush("red"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               dc.DrawText("X",i*TAILLE_CASE+10,j*TAILLE_CASE+5)
                           else :
                               dc.SetBrush(wx.Brush("white"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)

               elif self.Dem.state == "Win":
                   Avancement=self.Dem.w*self.Dem.h
                   for i in range(self.Dem.w):
                       for j in range(self.Dem.h):
                           if self.Dem.grilleM[i][j]=="X":
                               dc.SetBrush(wx.Brush("blue"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                           else :
                               dc.SetBrush(wx.Brush("white"))
                               dc.DrawRectangle(i*TAILLE_CASE,j*TAILLE_CASE,TAILLE_CASE,TAILLE_CASE)
                               dc.DrawText(self.Dem.grilleM[i,j],i*TAILLE_CASE+10,j*TAILLE_CASE+5)

               
	       
	       data=[]
	       data.append(self.name)
	       data.append(Avancement)
	       data=str(data)
	       s.send(data)
	       dc.DrawText("Nb mines left : %d"%count,20+4*TAILLE_CASE+self.Dem.w*TAILLE_CASE,5)
               dc.DrawText("Time : %.3f"%(self.Dem.fin-self.Dem.debut),10+self.Dem.w*TAILLE_CASE,5)

               # Affiche des differents joueurs et de leur score
               for i in range(self.nbPlayers):
                   dc.DrawText("%s : %.2f"%(self.tabPlayers[i],100.0*Avancement/(self.Dem.w*self.Dem.h)),10+self.Dem.w*TAILLE_CASE,5+(i+2)*TAILLE_CASE)




       def sortie(self,event):
           self.GetParent().Destroy()

       def newgame(self,event):
           self.Dem.Reset()
           self.init_buffer()

       def back(self,event):
           win = BoardFrame(None, -1, "Demineur",self.name, size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
           win.Show(True)
           self.GetParent().Destroy()

       def Discretisation(self,x,y):
               return x/TAILLE_CASE,y/TAILLE_CASE




class GameFrameRes(wx.Frame):
       def __init__( self, parent, ID, title, demineur, name, tabPlayers, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
               wx.Frame.__init__(self, parent, ID, title, pos, size, style)

               self.SetAutoLayout(True)
               self.GameWindowRes = DeminWindowRes(self,-1,demineur,name,tabPlayers)
               self.GameWindowRes.init_buffer()



class GameApp(wx.App):
	def OnInit(self):
		win = BoardFrame(None, -1, "Demineur", "","None","",size=(250,530),style = wx.DEFAULT_FRAME_STYLE)
		win.Show(True)
		self.SetTopWindow(win)
		return True



############ RESEAU ####################

#Fonction qui sert uniquement a lancer l'application demineur dans un thread pour pourvoir communiquer avec le serveur en meme temps

def ftamp(appli):
	appli.MainLoop()



#####################################


#Programme principal du client


#creation de la socket puis connexion
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",int(sys.argv[1])))


#lancement de l'application principale

#reception des informations provenant du serveur
#recept=s.recv(4000) #reception des joueurs et de la grille
#recept=eval(recept)
#joueurs=recept[0] #liste des joueurs
#nom_du_joueur=joueurs[0]
#pourcents=[0]*len(joueurs) #pourcentages de completion du demineur des joueurs
#grille=recept[1][1:] #grille du demineur
#difficulte=recept[1][0]

app1=GameApp()
app1.MainLoop()
app1.Destroy()

app = GameApp()
#lancement du demineur dans un thread
my_thread=thread.start_new_thread(ftamp,(app,))
app.Destroy()

#trans=""
#tant que le joueur ne gagne pas ni ne perd
#while trans!="l"+nom_du_joueur and trans!="w"+nom_du_joueur :
#	trans=s.recv(1000)
        #on recoit un pourcentage de completion
#	if trans[0]=="p":
#		joueur=trans[4:]
#		pourcents[joueurs.index(joueur)]=trans[1:4]
        #l'un des joueurs a perdu
#	elif trans[0]=="l":
#		joueur=trans[1:]
#		joueurs[joueurs.index(joueur)]="---" + joueur +"---"
        #l'un des joueurs a gagne
#	elif trans[0]=="w":
#		joueur=trans[1:]
#		pourcents[joueurs.index(joueur)]=100
#		joueurs[joueurs.index(joueur)]="+++" + joueur +"+++"


s.close()

